package com.github.barteksc.pdfviewer.scroll;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PointF;
import android.graphics.Rect;
import android.graphics.RectF;
import android.os.AsyncTask;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;

import com.github.barteksc.pdfviewer.PDFView;
import com.github.barteksc.pdfviewer.R;
import com.github.barteksc.pdfviewer.util.Util;

public class CropScrollHandle extends RelativeLayout implements ScrollHandle {
    private PDFView mPDFView;
    static private String TAG = "CropScrollHandle";

    private CropView mCropView;
    private ImageView mImageView;

    private PointF lastPos = new PointF();
    final static private int TYPE_NULL = 0x00;
    final static private int TYPE_MOVE = 0x01;
    final static private int TYPE_RESIE_TOP = 0X02;
    final static private int TYPE_RESIE_BOTTOM = 0X03;

    private int type = 0x00;

    private RectF[] area = new RectF[]{new RectF(), new RectF(), new RectF()};//<0 MOVE , 1&2 RESIZE

    public CropScrollHandle(Context context) {
        super(context);
    }
    public CropScrollHandle(Context pContext, CaptureBitmap pCaptureBitmap){
        super(pContext);
        mCaptureBitmap = pCaptureBitmap;
    }
    public void setScroll(float position){

    }

    public void setupLayout(PDFView pdfView){
        mPDFView = pdfView;

//        setOrientation(VERTICAL);

        RelativeLayout.LayoutParams lLayoutParams = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,  Util.getDP(getContext(), 200));
        lLayoutParams.addRule(RelativeLayout.CENTER_VERTICAL, RelativeLayout.TRUE);
        lLayoutParams.setMargins(0, 0, 0, 0);

        LayoutInflater.from(getContext()).inflate(R.layout.crop_layout, this);
        mImageView = findViewById(R.id.jiequ);
        mCropView = findViewById(R.id.cropView);

        mPDFView.addView(this, lLayoutParams);

        mImageView.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View pView) {
                Log.d(TAG, "onClick: ");
                new CapterPDFView().execute();
            }
        });
    }

    public void destroyLayout(){

    }

    public void setPageNum(int pageNum){

    }

    public boolean shown(){return getVisibility() == VISIBLE;}

    /**
     * Show handle
     */
    public void show(){
        setVisibility(VISIBLE);
    }

    /**
     * Hide handle immediately
     */
    public void hide(){
//        setVisibility(INVISIBLE);
    }

    /**
     * Hide handle after some time (defined by implementation)
     */
    public void hideDelayed(){

    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        Log.d(TAG, String.format("onTouchEvent: getx: %f , getRx: %f", event.getX(), event.getRawX()));
        PointF pos = new PointF(event.getX(), event.getY());

        switch (event.getAction()){
            case MotionEvent.ACTION_DOWN:{
                checkType(pos);
            }break;

            case MotionEvent.ACTION_MOVE:{
                if(type == TYPE_MOVE){
                    moveToPos(pos);
                }else if(type == TYPE_RESIE_BOTTOM || type == TYPE_RESIE_TOP){
                    resizePos(pos);
                }
            }break;

            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_CANCEL:{
                if(type == TYPE_MOVE){
                    moveToPos(pos);
                }else if(type == TYPE_RESIE_BOTTOM || type == TYPE_RESIE_TOP){
                    resizePos(pos);
                }

                type = TYPE_NULL;
            }break;
        }
        lastPos = pos;
        return true;
    }

    private void checkType(PointF pos){
        genArea();

        if(area[0].contains(pos.x, pos.y)){
            type = TYPE_MOVE;
        }

        if(area[1].contains(pos.x, pos.y)){
            type = TYPE_RESIE_TOP;
        }
        if(area[2].contains(pos.x, pos.y)){
            type = TYPE_RESIE_BOTTOM;
        }
    }

    private void genArea(){
        final float INSET = Util.getDP(getContext(), 50);
        float btm = mImageView.getHeight();

        float w = getWidth();
        float h = getHeight() - btm;

        area[0] = new RectF(0, INSET, getWidth(), getHeight() - INSET);
        area[1] = new RectF(0, 0, getWidth(), INSET);
        area[2] = new RectF(0, h - INSET, getWidth(), h);
    }

    private void moveToPos(PointF pos){
        Log.d(TAG, String.format("top:: %d botttom:: %d, x:: %d, y:: %d ,traX::%d , traY:: %d", getTop()
                ,getBottom(), (int)getX(), (int)getY(), (int)getTranslationX(), (int)getTranslationY()));

        float moveH = pos.y - lastPos.y;
        setY((int)(getY() + moveH));
    }

    private void resizePos(PointF pos){
        float resizeH = pos.y - lastPos.y;
        float h = mCropView.getHeight();

        Log.d(TAG, String.format("top:: %d botttom:: %d, x:: %d, y:: %d ,traX::%d , traY:: %d", getTop()
        ,getBottom(), (int)getX(), (int)getY(), (int)getTranslationX(), (int)getTranslationY()));

        RelativeLayout.LayoutParams lParams = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
        if(type == TYPE_RESIE_TOP){
            h = mCropView.getHeight() + resizeH * -1;
            lParams.topMargin = (int) getTop() + (int) resizeH;
            lParams.bottomMargin = (mPDFView.getHeight() - (int) getBottom());
            lParams.height = getHeight() + (int) resizeH * -1;
        }else if(type == TYPE_RESIE_BOTTOM){
            h = mCropView.getHeight() + resizeH;
            lParams.topMargin = getTop();
            lParams.bottomMargin = (mPDFView.getHeight() - (int) getBottom()) - (int) resizeH;
            lParams.height = getHeight() + (int) resizeH ;
        }

        if(h < Util.getDP(getContext(), 50)){
            return;
        }

//        LinearLayout.LayoutParams lLayoutParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 0);
//        lLayoutParams.weight = 1.0f;
//        mCropView.setLayoutParams(lLayoutParams);
        setLayoutParams(lParams);
    }

    class CapterPDFView extends AsyncTask<String, String, Bitmap>{
        @Override
        protected Bitmap doInBackground(String... pStrings) {
            mPDFView.setDrawingCacheEnabled(true);
            Bitmap bitmap = mPDFView.getDrawingCache();

            Rect cropRect = new Rect((int) CropScrollHandle.this.getX(), (int) CropScrollHandle.this.getY(),
                    (int) CropScrollHandle.this.getX() + mCropView.getWidth(),
                    (int) CropScrollHandle.this.getY() + mCropView.getHeight());

            int w  =mCropView.getWidth();
            int h = mCropView.getHeight();

            Bitmap targetBitmap = Bitmap.createBitmap( w, h,
                    Bitmap.Config.ARGB_8888);
            Canvas canvas = new Canvas(targetBitmap);
            Rect dst = new Rect(0, 0, w, h);

            Paint paint = new Paint();
            canvas.drawBitmap(bitmap, cropRect, dst, paint);
            bitmap.recycle();
            mPDFView.setDrawingCacheEnabled(false);

            return targetBitmap;
        }

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            CropScrollHandle.this.setVisibility(INVISIBLE);
        }

        @Override
        protected void onPostExecute(Bitmap pBitmap) {
            super.onPostExecute(pBitmap);
            CropScrollHandle.this.setVisibility(VISIBLE);
            if(mCaptureBitmap != null){
                mCaptureBitmap.doCapture(pBitmap);
            }
        }
    }

    private CaptureBitmap mCaptureBitmap;

    public void setCaptureBitmap(CaptureBitmap pCaptureBitmap) {
        mCaptureBitmap = pCaptureBitmap;
    }

    public interface CaptureBitmap{
        void doCapture(Bitmap pBitmap);
    }
}
